<?php 
/**
 * This file is part of DomAr.
 * 
 * DomAr is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * DomAr is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with DomAr.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * @link http://inditel.ee/
 * @copyright 2007-2009 Inditel Meedia OÜ
 * @author Oliver Leisalu <oliver@inditel.ee>
 */

/**
* @package DomAr
* @subpackage Property
*/
class DomArProperty_Text extends DomArProperty implements IDomArPropertyAlterTableListener,IDomArPropertyValidator,IDomArPropertyInsertListener,IDomArPropertyUpdateListener {
	
	protected $null = true;
	
	protected $empty = true;
	
	protected $index;
	
	public function __construct( $name, $null, $empty, $index) {
		parent::__construct( $name );
		$this->null = (bool)$null;
		$this->empty = (bool)$empty;
		$this->index = $index;
	}
	
	/**
	* @return Int Errors: 0-ok, 1-not string, 3 - empty or nulls
	*/
	public function validate( DomArObject $object, &$propertyValue, array &$customParams = array() ) {
		if( $this->null === false  && $propertyValue === NULL or $this->empty === false && $propertyValue == '' )
			return 3;
		
		if( $propertyValue !== NULL && !is_string($propertyValue) ) 
			return 1;
		
		return 0;
	}
		
	public function alterTable( DomArTable $table ) {
		$table->changeColumn( $this->name, 'text', true );
		
		if( $this->index )
			$ch2 = $table->changeIndex( $this->name, array($this->name), $this->index );
		else 
			$ch2 = $table->dropIndex( $this->name );	
	}
	
	public function insert( DomArObject $object, &$propertyValue, DomArValueSet $set  ) {
		$this->update( $object, $propertyValue, $set );
	}
	
	public function update( DomArObject $object, &$propertyValue, DomArValueSet $set ) {
		$set->set( $this->name, ($propertyValue !== NULL ? '\''.addslashes($propertyValue).'\'' : 'NULL') );
	}
	
}

/**
* @package DomAr
* @subpackage Property
*/
class DomArProperty_LongText extends DomArProperty_Text {
	
	public function alterTable( DomArTable $table ) {
		$table->changeColumn( $this->name, 'longtext', true );
		
		if( $this->index )
			$ch2 = $table->changeIndex( $this->name, array($this->name), $this->index );
		else 
			$ch2 = $table->dropIndex( $this->name );	
	}
	
}


/**
* @package DomAr
* @subpackage Property
*/
class DomArProperty_Char extends DomArProperty_Text {
	
	protected $length;
	protected $index;

	public function __construct( $name, $length, $null, $empty, $index = NULL ) {
		parent::__construct( $name, $null, $empty, NULL );
		$this->length = $length;
		$this->index = $index;
	}
	
	/**
	* @return Int Errors: 0-ok, 1-not string or too long, 2-not unique
	*/
	public function validate( DomArObject $object, &$propertyValue, array &$customParams = array() ) {
	
		if( $this->null === false  && $propertyValue === NULL or $this->empty === false && $propertyValue == '' )
			return 3;
		
		if( $propertyValue !== NULL && !is_string($propertyValue) or strlen($propertyValue) > $this->length )
			return 1;
		
		if( $this->checkValueUnique( $object, $propertyValue ) === false )
			return 2;
			
		return 0;
	}
	
	public function alterTable( DomArTable $table ) {
		$ch1 = $table->changeColumn( $this->name, 'varchar('.$this->length.')', true );
		if( $this->index )
			$ch2 = $table->changeIndex( $this->name, array($this->name), $this->index );
		else 
			$ch2 = $table->dropIndex( $this->name );
			
		return $ch1 or $ch2;
	}
	
	protected function checkValueUnique( DomArObject $object, &$propertyValue ) {
		// is unique?
		if( $this->index == 'unique' && $propertyValue !== NULL ) {
			try {
				$id = DomSql::selectOneQuery('SELECT id FROM '.$object->getDbTable().' WHERE `'.$this->name.'` = '.(is_numeric($propertyValue) ? $propertyValue : '\''.addslashes($propertyValue).'\'').' LIMIT 1','id');
				if( $id > 0 )
					return false;
			} catch( RuntimeException $e ) {
				if( $e->getCode() != 1146 )
					throw $e;
			}
		}
		return true;
	}
	
}




/**
* @package DomAr
* @subpackage Property
*/
class DomArProperty_Int extends DomArProperty_Char implements IDomArPropertyInitListener {

	public function __construct( $name, $length, $null, $index = NULL ) {
		parent::__construct( $name, $length, $null, false, NULL );
		$this->index = $index;
	}
	
	public function init( DomArObject $object, array &$values ) {
		return $values[$this->name] === NULL ? NULL : (int)$values[$this->name];
	}
	
	public function insert( DomArObject $object, &$propertyValue, DomArValueSet $set  ) {
		$this->update( $object, $propertyValue, $set );
	}
	
	public function update( DomArObject $object, &$propertyValue, DomArValueSet $set ) {
		$set->set( $this->name, ($propertyValue !== NULL ? (int)$propertyValue : 'NULL') );
	}
	
	/**
	* @return Int Errors: 0-ok, 1-not int or too long, 2-not unique
	*/
	public function validate( DomArObject $object, &$propertyValue, array &$customParams = array() ) {
		
		if( $this->null === false && $propertyValue === NULL )
			return 3;
		
		if( $propertyValue !== NULL && !is_int($propertyValue) )
			return 1;
		
		$length  = strlen($propertyValue) - (int)(substr($propertyValue,0,1)== '-');
		if( $length > $this->length )
			return 1;
		
		if( $this->checkValueUnique( $object, $propertyValue ) === false )
			return 2;
			
		return 0;
	}
	
	public function alterTable( DomArTable $table ) {
		$ch1 = $table->changeColumn( $this->name, 'int('.$this->length.')', true );
		if( $this->index )
			$ch2 = $table->changeIndex( $this->name, array($this->name), $this->index );
		else 
			$ch2 = $table->dropIndex( $this->name );
		return $ch1 or $ch2;
	}
	
}



/**
* @package DomAr
* @subpackage Property
*/
class DomArProperty_Float extends DomArProperty_Int {
	
	protected $afterComma;
	
	public function __construct( $name, $length, $afterComma, $null, $index = NULL ) {
		parent::__construct( $name, $length, $null, $index );
		$this->afterComma = $afterComma;
	}
	
	/**
	* @return Mixed
	*/
	public function init( DomArObject $object, array &$values ) {
		return (float)$values[$this->name];
	}
	
	public function insert( DomArObject $object, &$propertyValue, DomArValueSet $set  ) {
		$this->update( $object, $propertyValue, $set );
	}
	
	public function update( DomArObject $object, &$propertyValue, DomArValueSet $set ) {
		$set->set( $this->name, ($propertyValue !== NULL ? (float)$propertyValue : 'NULL') );
	}
	
	/**
	* @return Int Errors: 0-ok, 1-not float or too long, 2-not unique
	*/
	public function validate( DomArObject $object, &$propertyValue, array &$customParams = array() ) {
		// basic isFloat validation
		$p = $propertyValue;	
		if( $p < 0 ) $p *= -1;
		$nr = explode('.',$p);
		
		if( $this->null === false && $propertyValue === NULL )
			return 3;
		
		if( $propertyValue !== NULL && !is_int($propertyValue) && !is_float($propertyValue) )
			return 1;
		
		if( strlen($nr[0]) > $this->length-$this->afterComma or strlen($nr[1]) > $this->afterComma )
			return 1;
		
		if( $this->checkValueUnique( $object, $propertyValue ) === false )
			return 2;
			
		return 0;
	}
	
	public function alterTable( DomArTable $table ) {
		$ch1 = $table->changeColumn( $this->name, 'float('.$this->length.','.$this->afterComma.')', true );
		if( $this->index )
			$ch2 = $table->changeIndex( $this->name, array($this->name), $this->index );
		else 
			$ch2 = $table->dropIndex( $this->name );
		return $ch1 or $ch2;
	}
	
}




/**
* @package DomAr
* @subpackage Property
*/
class DomArProperty_Bool extends DomArProperty_Int {
	
	public function __construct( $name, $null, $index = NULL ) {
		parent::__construct( $name, 1, $null, $index );
	}

	public function init( DomArObject $object, array &$values ) {
		if( $values[$this->name] == '' ) 
			return NULL;
		
		return (bool)$values[$this->name];
	}
	
	public function insert( DomArObject $object, &$propertyValue, DomArValueSet $set  ) {
		$this->update( $object, $propertyValue, $set );
	}
	
	public function update( DomArObject $object, &$propertyValue, DomArValueSet $set ) {
		$set->set( $this->name, $propertyValue === NULL ? 'NULL' : (int)(bool)$propertyValue );
	}
	
	/**
	* @return Int Errors: 0-ok, 1-not bool
	*/
	public function validate( DomArObject $object, &$propertyValue, array &$customParams = array() ) {
		if( $this->null === false && $propertyValue === NULL )
			return 3;
			
		if( $this->null === true && $propertyValue === NULL )
			return 0;
		
		return (int)!is_bool($propertyValue);
	}
	
	public function alterTable( DomArTable $table ) {
		$ch1 = $table->changeColumn( $this->name, 'tinyint(1)', true );
		if( $this->index )
			$ch2 = $table->changeIndex( $this->name, array($this->name), $this->index );
		else 
			$ch2 = $table->dropIndex( $this->name );
		return $ch1 or $ch2;
	}

}


/**
* @package DomAr
* @subpackage Property
*/
class DomArProperty_Array extends DomArProperty_Text implements IDomArPropertyInitListener {
	
	public function __construct( $name, $null) {
		parent::__construct( $name, $null, true, NULL );
	}
	
	public function init( DomArObject $object, array &$values ) {
		$init = unserialize($values[$this->name]);
		if( is_array($init) === true  )
			return $init;
		else
			return array();
	}
	
	public function insert( DomArObject $object, &$propertyValue, DomArValueSet $set  ) {
		$this->update( $object, $propertyValue, $set );
	}
	
	public function update( DomArObject $object, &$propertyValue, DomArValueSet $set ) {
		$set->set( $this->name, '\''.addslashes(serialize($propertyValue)).'\'' );
	}
	
	/**
	* @return Int Errors: 0-ok, 1-not array
	*/
	public function validate( DomArObject $object, &$propertyValue, array &$customParams = array() ) {
		return (int)!(is_array($propertyValue) or $this->null === true && $propertyValue === NULL );
	}
	
	public function alterTable( DomArTable $table ) {
		return $table->changeColumn( $this->name, 'longtext', true );
	}

}


/**
* @package DomAr
* @subpackage Property
*/
class DomArProperty_Enum extends DomArProperty implements IDomArPropertyBeforeSetListener, IDomArPropertyAlterTableListener,IDomArPropertyValidator,IDomArPropertyInsertListener,IDomArPropertyUpdateListener {
	
	protected $values = array();
	
	protected $index;
	
	public function __construct( $name, array $values, $index) {
		parent::__construct( $name );
		$this->values = $values;
		$this->index = $index;
	}
	
	/**
	* @return Int Errors: 0-ok, 1-bad enum value
	*/
	public function validate( DomArObject $object, &$propertyValue, array &$customParams = array() ) {

		if( $propertyValue == NULL or is_int($propertyValue) && isset($this->values[$propertyValue]) or is_string($propertyValue) && in_array($propertyValue,$this->values) ) 
			return 0;
		
		return 1;
	}
	
	public function beforeSet( DomArObject $object, &$oldPropertyValue, &$newPropertyValue ) {

		if( is_int($newPropertyValue) )
			$newPropertyValue = $this->values[$newPropertyValue];

		return $newPropertyValue;
	}
		
	public function alterTable( DomArTable $table ) {
		$values = '';
		foreach( $this->values as $value ) {
			$values .= ',\''.addslashes($value).'\'';
		}
		
		$table->changeColumn( $this->name, 'ENUM('.substr($values,1).')', true );
		
		if( $this->index )
			$ch2 = $table->changeIndex( $this->name, array($this->name), $this->index );
		else 
			$ch2 = $table->dropIndex( $this->name );	
	}
	
	public function insert( DomArObject $object, &$propertyValue, DomArValueSet $set  ) {
		$this->update( $object, $propertyValue, $set );
	}
	
	public function update( DomArObject $object, &$propertyValue, DomArValueSet $set ) {
		$set->set( $this->name, ($propertyValue != '' ? '\''.addslashes($propertyValue).'\'' : 'NULL') );
	}
	
}



/**
* @package DomAr
* @subpackage Property
*/
class DomArProperty_Set extends DomArProperty implements IDomArPropertyInitListener, IDomArPropertyBeforeSetListener, IDomArPropertyAlterTableListener,IDomArPropertyValidator,IDomArPropertyInsertListener,IDomArPropertyUpdateListener {
	
	protected $values = array();
	
	protected $index;
	
	public function __construct( $name, array $values, $index) {
		parent::__construct( $name );
		$this->values = $values;
		$this->index = $index;
	}
	
	
	public function init( DomArObject $object, array &$values ) {
		return explode(',',$values[$this->name]);
	}
	
	/**
	* @return Int Errors: 0-ok, 1-bad enum value
	*/
	public function validate( DomArObject $object, &$propertyValue, array &$customParams = array() ) {
		
		if( $propertyValue == NULL )
			return 0;
		
		if( !is_array($propertyValue) )
			return 1;
			
		foreach( $propertyValue as $val ) {
			if( !(is_int($val) && isset($this->values[$val]) or is_string($val) && in_array($val,$this->values)) ) {
				return 1;
			}
		}
		return 0;
	}
	
	public function beforeSet( DomArObject $object, &$oldPropertyValue, &$newPropertyValue ) {
		if( is_array($newPropertyValue) === true ) {
			foreach( $newPropertyValue as &$val ) {
				if( is_int($val) === true )
					$val = $this->values[$val];
			}
		}
		
		return $newPropertyValue;
	}
		
	public function alterTable( DomArTable $table ) {
		$values = '';
		foreach( $this->values as $value ) {
			$values .= ',\''.addslashes($value).'\'';
		}
		
		$table->changeColumn( $this->name, 'SET('.substr($values,1).')', true );
		
		if( $this->index )
			$ch2 = $table->changeIndex( $this->name, array($this->name), $this->index );
		else 
			$ch2 = $table->dropIndex( $this->name );	
	}
	
	public function insert( DomArObject $object, &$propertyValue, DomArValueSet $set  ) {
		$this->update( $object, $propertyValue, $set );
	}
	
	public function update( DomArObject $object, &$propertyValue, DomArValueSet $set ) {
		if( is_array($propertyValue) ) {
			$values = array();
			foreach( $propertyValue as $val )
				$values[] = addslashes( $val );
			$values = '(\''.implode(',', $values).'\')';
		} else
			$values = 'NULL';
		
		$set->set( $this->name, $values );
	}
	
}


/**
* @package DomAr
* @subpackage Property
*/
class DomArProperty_Number extends DomArProperty implements IDomArPropertyInitListener,IDomArPropertyAlterTableListener,IDomArPropertyValidator,IDomArPropertyInsertListener,IDomArPropertyUpdateListener{
	
	protected $length;
	
	protected $decimals;
	
	protected $in;
	
	protected $between;
	
	protected $betweenArgs;
	
	protected $unsigned;
	
	protected $null = true;
	
	protected $index;
	
	public function __construct( $name, $length, $decimals, $null, $unsigned, $index, array $in ) {
		parent::__construct( $name, $length, $index );
		$this->length = $length;
		$this->decimals = $decimals;
		$this->null = $null;
		$this->unsigned = $unsigned;
		$this->index = $index;
		$this->in = $in;
	}
	
	/**
	* @return Number
	*/
	public function init( DomArObject $object, array &$values ) {
		if( $this->decimals > 0 or $this->length > 8 )
			return (float)$values[$this->name];
		else
			return (int)$values[$this->name];
	}
	
	public function insert( DomArObject $object, &$propertyValue, DomArValueSet $set  ) {
		$this->update( $object, $propertyValue, $set );
	}
	
	public function update( DomArObject $object, &$propertyValue, DomArValueSet $set ) {
		$set->set( $this->name, $this->getDatabaseValue($propertyValue) );
	}
	
	/**
	* @return Int Errors: 0-ok, 1-not in correct format, 2-not unique, 4-not in allowed values, 3-empty/null is not allowed
	*/
	public function validate( DomArObject $object, &$propertyValue, array &$customParams = array() ) {
		
		if( $propertyValue === NULL ) {
			if( $this->null === false)
				return 3;
			
			return 0;
				
		// test float
		} else if( $this->decimals > 0) {
			if( !is_float($propertyValue) )
				return 1;
			
			$nr = explode('.',abs($propertyValue));
			if( strlen($nr[0]) > $this->length-$this->decimals or strlen($nr[1]) > $this->decimals )
				return 1;
		
		// test int
		} else {
			if( !is_int($propertyValue) && !is_float($propertyValue) )
				return 1;
			
			if( strlen($nr[0]) > $this->length )
				return 1;
		}
		
		// check that the value is unique. (If null is allowed and value is empty, then check will be ignored.)
		if( $this->index == 'unique' && ($this->null === true && empty($propertyValue) === false) ) {
			try {
				$id = DomSql::selectOneQuery('SELECT id FROM '.$object->getDbTable().' WHERE `'.$this->name.'` = '.$this->getDatabaseValue($propertyValue).' LIMIT 1','id');
				if( $id > 0 )
					return 2;
			} catch( RuntimeException $e ) {
				if( $e->getCode() != 1146 )
					throw $e;
			}
		}
		
		// in validator stuff.
		if( empty($this->in) === false ) {
			$ok = false;
			foreach( $this->in as $value ) {
				$ok = is_array($value) === true ? $value[0] <= $propertyValue && $value[1] >= $propertyValue : $value == $propertyValue;
				if( $ok === true ) {
					break;
				}
			}
			if( $ok === false )
				return 4;
		}
			
		return 0;
	}
	
	public function alterTable( DomArTable $table ) {
		
		if( $this->decimals <= 0 ) {
			if( $this->length <= 2 ) {
				$type = 'tinyint';
			} else if( $this->length <= 4 ) {
				$type = 'smallint';
			} else if( $this->length <= 6 ) {
				$type = 'mediumint';
			} else if( $this->length <= 9 ) {
				$type = 'int';
			} else {
				$type = 'bigint';
			}
		} else {
			$realLength = $this->length + $this->decimals;
			if( $realLength <= 23) {
				$type = 'float('.(int)$this->length.','.(int)$this->decimals.')';
			} else {
				$type = 'double('.(int)$this->length.','.(int)$this->decimals.')';
			}	
		}
		$ch1 = $table->changeColumn( $this->name, $type, $this->null );

		if( $this->index )
			$ch2 = $table->changeIndex( $this->name, array($this->name), $this->index );
		else 
			$ch2 = $table->dropIndex( $this->name );
					
		return true;
	}
	
	private function getDatabaseValue( $value ) {
		if( empty($value) === true ) {
			if( $this->null === true )
				return 'NULL';
			else
				return 0;
		} else
			return $value;
	}
	
}


/**
 * You can give email in as $item->email  = array($email1, $email2); Then emails are checked for match. If they don't
 * validation error 4 is raised.
 * 
* @package DomAr
* @subpackage Property
*/
class DomArProperty_Email extends DomArProperty_Char implements IDomArPropertyBeforeSetListener {
	
	public function __construct( $name, $null, $empty, $index = NULL ) {
		parent::__construct( $name, 255, $null, $empty, $index );
	}
	
	public function beforeSet( DomArObject $object, &$oldPropertyValue, &$newPropertyValue ) {
		if( is_array($newPropertyValue) )
			$newPropertyValue = $newPropertyValue[0];
	}
	/**
	* @return Int Errors: 0-ok, 1-not correct email, 2-not unique, 3-null or empty is not allowed, 4-email1!=email2
	*/
	public function validate( DomArObject $object, &$propertyValue, array &$customParams = array() ) {
		$testValue = $propertyValue;
		if( is_array($propertyValue) ) {
			if( $propertyValue[0] != $propertyValue[1] )
				return 4;
			else
				$testValue = $propertyValue[0];
		}

		if( $this->null === false && $testValue === NULL )
			return 3;
			
		if( $this->empty === false && $testValue == '' )
			return 3;
		
		if( $testValue != '' && !preg_match('/^([a-zA-Z0-9_-])+([a-zA-Z0-9.+_-])*([a-zA-Z0-9_-])+@([[:alnum:]]+(\.|-|_)?)+[[:alnum:]]\.[[:alpha:]]{2,}$/', $testValue ) )
			return 1;
		
		if( $this->checkValueUnique( $object, $testValue ) === false )
			return 2;
			
		return 0;
	}
}


/**
 * This handler helps with handling password.
 * You can update password this way $item->password = array($pass1, $pass2)
 * Then comparison is made if pass1 == pass2. If not validation error with code 3 is raised.
 * 
 * When password is set and you call $item->password = '' then password is not changed to nothing! It keeps old password. So if you get password from
 * REQUEST you don't need to worry about if user wrote it or not. If its empty, if won't be changed. If password is empty and you try to set it '' then 
 * validation error is raised! (Same for $item->password = array('',''); )
 * 
 * Password is encoded with md5 automatically.
 * <code>
 * $item->password = 'secret99';
 * echo $item->password; // writes a7e938134bb0fb0d90a7c7f81dc32ddf
 * // you can't get password back as simle string!
 * </code>
 * 
 * Check criterias: has lower case letters, has upper case letters, has numbers and length
 *
 * Strength values:
 * <ul>
 * <li>3 means that password must have all criterias except length. Allowed are: AAAaaa000 </li>
 * <li>2 means that password must have at least 2 criterias except length. Allowed are: AAAaaa, AAA000, aaa000 </li>
 * <li>1 means that password must have at least 1 criteria except length. Allowed are: AAA,aaa,000 </li>
 * <li>0 means that no criteria checks are done. (Only length is checked) </li>
 * </ul>
 * 
* @package DomAr
* @subpackage Property
*/
class DomArProperty_Password extends DomArProperty_Char implements IDomArPropertyBeforeSetListener {
	
	protected $passLength;
	
	protected $strength;
	
	public function __construct( $name, $null, $empty, $passLength = 6, $strength = 2 ) {
		parent::__construct( $name, 50, $null, $empty );
		$this->passLength = (int)$passLength;
		$this->strength = (int)$strength;
	}
	
	public function beforeSet( DomArObject $object, &$oldPropertyValue, &$newPropertyValue ) {
		
		if( is_array($newPropertyValue) )
			$newPropertyValue = $newPropertyValue[0];
		
		if( $newPropertyValue == '' && $newPropertyValue !== NULL )
			$newPropertyValue = $oldPropertyValue;
		else
			$newPropertyValue = $this->encodePassword($newPropertyValue);
	}
	
	/**
	 * Error codes
	 * 
	 * 0 - on ok
	 * 3 - value is empty or null, but not allowed 
	 * 4 - two given passwords don't match
	 * 5 - if too short
	 * 6 - if doesn't containt enaugh symbols
	 * 7 - old password is not same as current password
	 * 
	 * @param String $value
	 * @param Int $strength [1,2,3]
	 * @param Int $length Password minimum length
	 * @return Int Result code 
	 */
	public function validate( DomArObject $object, &$propertyValue, array &$customParams = array() ) {
		
		$value = $propertyValue;
		if( is_array($propertyValue) ) {
			if( $propertyValue[0] != $propertyValue[1] )
				return 4;
			else
				$value = $propertyValue[0];
			
			if( isset( $propertyValue[2]) && $this->encodePassword($propertyValue[2]) != $object->{$this->name} ) {
				return 7;
			}
		}
	
		//if( ($value === NULL or $value === '') && $object->{$this->name} == '' )
		//	return 0;
		if( $this->null === true && $value === NULL or $this->empty === true && $value === '')
			return 0;
			
		if( $this->null === false && $value === NULL )
			return 3;
			
		if( $this->empty === false && $value == '' )
			return 3;
			
			

		if( !is_string($value) )
			return 1;
		
		if( strlen($value) < $this->passLength ) 
			return 5;
		
		if( $this->strength <= 0 )
			return 0;
			
		for( $i=0; $i < strlen($value); $i++ ) {
			$hasLowerLetters = (int)(bool)preg_match('/[a-z]/', $value);
			$hasUpperLetters = (int)(bool)preg_match('/[A-Z]/', $value);
			$hasNumbers = (int)(bool)preg_match('/[0-9]/', $value);
		}
		
		return ($hasLowerLetters + $hasUpperLetters + $hasNumbers >= $this->strength) ? 0 : 6;
	}

	public function encodePassword( $password ) {
		return md5($password);
	}
}




?>